package com.hbean.system.listener;

import com.hbean.system.config.SysCache;
import com.hbean.system.config.SysConfig;
import com.hbean.system.websocket.WebSocketServer;
import com.hbean.utils.HUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: @WebListener注解为声明此类为Listener，无需再进行配置，
 * 唯一注意的是，使用注解的方式声明Listener时，需要再main函数类上添加@ServletComponentScan
 * @Project: hbean
 * @Author: hjibo
 * @CreateDate: 2018-10-08 11:03
 * @ModificationHistory:
 */

@Slf4j
@WebListener
public class SessionListener implements HttpSessionListener,HttpSessionAttributeListener {

    @Autowired
    private SysCache sysCache;
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * key:userId value:session 用户单点登录判断时使用
     */
    public static Map<String, HttpSession> sessionMap = new ConcurrentHashMap<>();

    /**
     * Session创建时执行当前方法
     * @param httpSessionEvent
     */
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {

        //设置session过期时间
        httpSessionEvent.getSession().setMaxInactiveInterval(SysConfig.sessionOutTime);

    }

    /**
     * Session销毁时执行当前方法
     * @param httpSessionEvent
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

        //如果session中用户信息不为空，则清除用户信息
        String userId = (String) httpSessionEvent.getSession().getAttribute("userId");
        if(HUtil.isNotEmpty(userId)) {

            //清除用户信息
            sessionMap.remove(userId);
            httpSessionEvent.getSession().removeAttribute("userId");

            //将下线信息推送给所有用户
            Map dataMap = new HashMap();
            dataMap.put("loginOffInfo", sysCache.getSysUserByID(userId).getSu01()+" 下线了（过期）！");
            webSocketServer.sendMessageToAll(HUtil.mapToJsonStr(dataMap));

            //如果session过期，往页面推送一条消息，告诉页面关闭当前websocket
            Map dataMap0 = new HashMap();
            dataMap0.put("timeOutOfSession", "登录已过期，请重新登录");
            webSocketServer.sendMessage(HUtil.mapToJsonStr(dataMap0),userId);

        }

   }

    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        log.info("Session attributeAdded");
    }

    /**
     * Session移除某个属性时执行当前方法
     * @param httpSessionBindingEvent
     */
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        log.info("Session attributeRemoved");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        log.info("Session attributeReplaced");
    }

    public SessionListener() {
        log.info("###### 注册Session监听器 ######");
    }
}
